#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI 自诊断触发器
当测试或检查失败时，自动触发 AI 诊断
"""
import subprocess
import sys
from pathlib import Path

# Windows 环境 UTF-8 编码设置
if sys.platform == 'win32':
    import io
    if hasattr(sys.stdout, 'buffer'):
        sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    if hasattr(sys.stderr, 'buffer'):
        sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')


def run_command(cmd: str) -> tuple[int, str, str]:
    """运行命令并返回结果"""
    result = subprocess.run(
        cmd,
        shell=True,
        capture_output=True,
        text=True,
        encoding='utf-8',
        errors='replace',  # 替换无法解码的字符，避免 UnicodeDecodeError
    )
    return result.returncode, result.stdout, result.stderr


def check_errors() -> bool:
    """检查是否存在错误"""
    print("[Pre-commit] 检查代码质量...")

    # 运行 ruff
    ruff_code, ruff_out, ruff_err = run_command("ruff check backend/app")

    # 运行 mypy
    mypy_code, mypy_out, mypy_err = run_command("mypy backend/app --strict")

    # 运行 pytest
    pytest_code, pytest_out, pytest_err = run_command("pytest -q --maxfail=1 --disable-warnings")

    # 判断是否有错误
    has_errors = any([ruff_code != 0, mypy_code != 0, pytest_code != 0])

    if has_errors:
        print("[Pre-commit] 发现错误，准备触发 AI 诊断...")

        # 保存错误日志
        reports_dir = Path("reports")
        reports_dir.mkdir(exist_ok=True)

        error_log = reports_dir / "last_error.log"
        with open(error_log, "w", encoding="utf-8") as f:
            f.write("=== Ruff 检查结果 ===\n")
            f.write(f"Return Code: {ruff_code}\n")
            f.write(f"STDOUT:\n{ruff_out}\n")
            f.write(f"STDERR:\n{ruff_err}\n\n")

            f.write("=== MyPy 检查结果 ===\n")
            f.write(f"Return Code: {mypy_code}\n")
            f.write(f"STDOUT:\n{mypy_out}\n")
            f.write(f"STDERR:\n{mypy_err}\n\n")

            f.write("=== Pytest 测试结果 ===\n")
            f.write(f"Return Code: {pytest_code}\n")
            f.write(f"STDOUT:\n{pytest_out}\n")
            f.write(f"STDERR:\n{pytest_err}\n\n")

        print(f"[Pre-commit] 错误日志已保存到: {error_log}")
        return True
    else:
        print("[Pre-commit] 所有检查通过!")
        return False


def trigger_ai_diagnosis() -> None:
    """触发 AI 诊断（集成智能诊断工作流）"""
    print("[Pre-commit] 触发 AI 自诊断...")
    print("[Pre-commit] 错误日志: reports/last_error.log")

    try:
        # 导入智能诊断工作流
        from smart_diagnose import AIProvider, SmartDiagnosticWorkflow

        # 检查是否配置了 API 密钥
        import os

        if os.getenv("OPENAI_API_KEY"):
            provider = AIProvider.OPENAI
            print("[Pre-commit] 使用 OpenAI 进行诊断")
        elif os.getenv("ANTHROPIC_API_KEY"):
            provider = AIProvider.ANTHROPIC
            print("[Pre-commit] 使用 Anthropic Claude 进行诊断")
        else:
            provider = AIProvider.MOCK
            print("[Pre-commit] 未配置 API 密钥，使用模拟模式")
            print("[Pre-commit] 提示：在 .env 中配置 OPENAI_API_KEY 或 ANTHROPIC_API_KEY")

        # 运行诊断
        workflow = SmartDiagnosticWorkflow(provider=provider)
        result = workflow.run_full_diagnostic()

        if result["status"] == "completed":
            print(f"\n[Pre-commit] AI 诊断完成!")
            print(f"[Pre-commit] 详细报告: {result['report_file']}")

    except ImportError:
        print("[Pre-commit] 智能诊断模块未安装")
        print("[Pre-commit] 提示：确保 smart_diagnose.py 和 ai_client.py 在同一目录")
    except Exception as e:
        print(f"[Pre-commit] AI 诊断失败: {e}")
        print("[Pre-commit] 可以手动查看 reports/last_error.log 分析错误")


def main() -> int:
    """主函数"""
    print("[Pre-commit] 启动 AI 自诊断检查...")

    # 检查是否有错误
    has_errors = check_errors()

    if has_errors:
        # 触发 AI 诊断
        trigger_ai_diagnosis()
        return 1

    return 0


if __name__ == "__main__":
    sys.exit(main())
